//
//  DMLifecycleEventDispatcher.m
//  DualMediationSDK
//
//  生命周期事件分发器实现
//

#import "DMLifecycleEventDispatcher.h"
#import "DMLifecycleStateManager.h"
#import "DMLifecycleDelegateRegistry.h"

#pragma mark - 分发统计信息实现

@implementation DMEventDispatchStatistics

- (NSTimeInterval)averageDispatchTime {
    if (self.successfulDispatches == 0) {
        return 0;
    }
    return self.totalDispatchTime / self.successfulDispatches;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"<DMEventDispatchStatistics: total=%lu, success=%lu, failed=%lu, avgTime=%.3fms>",
            (unsigned long)self.totalListeners,
            (unsigned long)self.successfulDispatches,
            (unsigned long)self.failedDispatches,
            self.averageDispatchTime * 1000];
}

@end

#pragma mark - 分发日志项

@interface DMDispatchLogItem : NSObject
@property (nonatomic, assign) DMLifecycleEvent event;
@property (nonatomic, assign) DMLifecycleState state;
@property (nonatomic, strong) NSDate *timestamp;
@property (nonatomic, assign) DMEventDispatchResult result;
@property (nonatomic, assign) NSTimeInterval duration;
@property (nonatomic, assign) NSUInteger listenerCount;
@property (nonatomic, strong, nullable) NSString *errorDescription;
@end

@implementation DMDispatchLogItem
@end

#pragma mark - 事件分发器实现

@interface DMLifecycleEventDispatcher ()

// 分发控制
@property (nonatomic, assign) BOOL dispatchingPaused;
@property (nonatomic, strong) NSMutableArray *pendingDispatches;

// 统计信息
@property (nonatomic, strong) DMEventDispatchStatistics *statistics;
@property (nonatomic, strong) NSMutableArray<DMDispatchLogItem *> *dispatchLog;
@property (nonatomic, assign) NSUInteger maxLogCount;

// 错误处理
@property (nonatomic, copy, nullable) DMDispatchErrorHandler errorHandler;

// 调试支持
@property (nonatomic, assign) BOOL debugModeEnabled;

// 线程安全
@property (nonatomic, strong) dispatch_queue_t dispatchQueue;
@property (nonatomic, strong) dispatch_queue_t statisticsQueue;
@property (nonatomic, strong) dispatch_group_t dispatchGroup;

@end

@implementation DMLifecycleEventDispatcher

static DMLifecycleEventDispatcher *_sharedDispatcher = nil;
static dispatch_once_t onceToken;

#pragma mark - 单例实现

+ (instancetype)sharedDispatcher {
    dispatch_once(&onceToken, ^{
        _sharedDispatcher = [[self alloc] init];
    });
    return _sharedDispatcher;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setupDispatcher];
    }
    return self;
}

- (void)setupDispatcher {
    // 创建队列
    _dispatchQueue = dispatch_queue_create("com.dualmediationsdk.event.dispatcher", DISPATCH_QUEUE_CONCURRENT);
    _statisticsQueue = dispatch_queue_create("com.dualmediationsdk.event.statistics", DISPATCH_QUEUE_SERIAL);
    _dispatchGroup = dispatch_group_create();
    
    // 初始化配置
    _asyncDispatchEnabled = YES;
    _dispatchTimeout = 5.0;
    _statisticsEnabled = NO;
    _maxRetryCount = 3;
    _dispatchingPaused = NO;
    _debugModeEnabled = NO;
    
    // 初始化容器
    _pendingDispatches = [NSMutableArray array];
    _statistics = [[DMEventDispatchStatistics alloc] init];
    _dispatchLog = [NSMutableArray array];
    _maxLogCount = 1000;
}

#pragma mark - 生命周期事件分发

- (DMEventDispatchResult)dispatchLifecycleEvent:(DMLifecycleEvent)event withState:(DMLifecycleState)state {
    return [self dispatchLifecycleEvent:event withState:state userInfo:nil];
}

- (DMEventDispatchResult)dispatchLifecycleEvent:(DMLifecycleEvent)event userInfo:(nullable NSDictionary *)userInfo {
    // 获取当前生命周期状态
    DMLifecycleState currentState = [[DMLifecycleStateManager sharedManager] getCurrentState];
    return [self dispatchLifecycleEvent:event withState:currentState userInfo:userInfo];
}

- (DMEventDispatchResult)dispatchLifecycleEvent:(DMLifecycleEvent)event 
                                      withState:(DMLifecycleState)state 
                                       userInfo:(nullable NSDictionary *)userInfo {
    if (self.dispatchingPaused) {
        [self logDebug:@"Event dispatch paused, skipping event %@", DMLifecycleEventDescription(event)];
        return DMEventDispatchResultFailure;
    }
    
    NSDate *startTime = [NSDate date];
    DMDispatchLogItem *logItem = [self createLogItemForEvent:event state:state timestamp:startTime];
    
    // 获取监听器
    NSArray<id<DMLifecycleEventListener>> *listeners = [[DMLifecycleDelegateRegistry sharedRegistry] getAllLifecycleDelegates];
    
    if (listeners.count == 0) {
        logItem.result = DMEventDispatchResultNoListeners;
        logItem.duration = [[NSDate date] timeIntervalSinceDate:startTime];
        [self addLogItem:logItem];
        return DMEventDispatchResultNoListeners;
    }
    
    logItem.listenerCount = listeners.count;
    
    // 分发事件
    DMEventDispatchResult result = [self performEventDispatch:listeners 
                                                         event:event 
                                                         state:state 
                                                      userInfo:userInfo];
    
    // 更新日志和统计
    logItem.result = result;
    logItem.duration = [[NSDate date] timeIntervalSinceDate:startTime];
    [self addLogItem:logItem];
    [self updateStatistics:result duration:logItem.duration listenerCount:listeners.count];
    
    return result;
}

- (void)dispatchLifecycleEventAsync:(DMLifecycleEvent)event 
                          withState:(DMLifecycleState)state 
                         completion:(nullable void(^)(DMEventDispatchResult result, DMEventDispatchStatistics *statistics))completion {
    [self dispatchLifecycleEventAsync:event withState:state userInfo:nil completion:completion];
}

- (void)dispatchLifecycleEventAsync:(DMLifecycleEvent)event 
                          withState:(DMLifecycleState)state 
                           userInfo:(nullable NSDictionary *)userInfo
                         completion:(nullable void(^)(DMEventDispatchResult result, DMEventDispatchStatistics *statistics))completion {
    if (!self.asyncDispatchEnabled) {
        DMEventDispatchResult result = [self dispatchLifecycleEvent:event withState:state userInfo:userInfo];
        if (completion) {
            completion(result, self.statisticsEnabled ? self.statistics : nil);
        }
        return;
    }
    
    dispatch_group_enter(self.dispatchGroup);
    
    dispatch_async(self.dispatchQueue, ^{
        DMEventDispatchResult result = [self dispatchLifecycleEvent:event withState:state userInfo:userInfo];
        
        dispatch_group_leave(self.dispatchGroup);
        
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(result, self.statisticsEnabled ? self.statistics : nil);
            });
        }
    });
}

#pragma mark - 状态变化分发

- (DMEventDispatchResult)dispatchStateChange:(DMLifecycleState)previousState 
                                currentState:(DMLifecycleState)currentState 
                               triggerEvent:(DMLifecycleEvent)event {
    if (self.dispatchingPaused) {
        [self logDebug:@"State change dispatch paused, skipping %@ -> %@", 
         DMLifecycleStateDescription(previousState), DMLifecycleStateDescription(currentState)];
        return DMEventDispatchResultFailure;
    }
    
    NSDate *startTime = [NSDate date];
    
    // 获取监听器
    NSArray<id<DMLifecycleEventListener>> *listeners = [[DMLifecycleDelegateRegistry sharedRegistry] getAllLifecycleDelegates];
    
    if (listeners.count == 0) {
        return DMEventDispatchResultNoListeners;
    }
    
    NSUInteger successCount = 0;
    NSUInteger failureCount = 0;
    
    for (id<DMLifecycleEventListener> listener in listeners) {
        @try {
            if ([listener respondsToSelector:@selector(onLifecycleStateChanged:currentState:triggerEvent:)]) {
                [listener onLifecycleStateChanged:previousState currentState:currentState triggerEvent:event];
                successCount++;
            }
        } @catch (NSException *exception) {
            failureCount++;
            [self handleDispatchError:[NSError errorWithDomain:@"DMLifecycleEventDispatcher" 
                                                          code:-1 
                                                      userInfo:@{NSLocalizedDescriptionKey: exception.reason ?: @"Unknown error"}]
                                event:event 
                             listener:listener];
        }
    }
    
    NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startTime];
    DMEventDispatchResult result = [self determineDispatchResult:successCount failureCount:failureCount totalCount:listeners.count];
    
    [self updateStatistics:result duration:duration listenerCount:listeners.count];
    
    return result;
}

- (void)dispatchStateChangeAsync:(DMLifecycleState)previousState 
                    currentState:(DMLifecycleState)currentState 
                   triggerEvent:(DMLifecycleEvent)event
                     completion:(nullable void(^)(DMEventDispatchResult result, DMEventDispatchStatistics *statistics))completion {
    if (!self.asyncDispatchEnabled) {
        DMEventDispatchResult result = [self dispatchStateChange:previousState currentState:currentState triggerEvent:event];
        if (completion) {
            completion(result, self.statisticsEnabled ? self.statistics : nil);
        }
        return;
    }
    
    dispatch_group_enter(self.dispatchGroup);
    
    dispatch_async(self.dispatchQueue, ^{
        DMEventDispatchResult result = [self dispatchStateChange:previousState currentState:currentState triggerEvent:event];
        
        dispatch_group_leave(self.dispatchGroup);
        
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(result, self.statisticsEnabled ? self.statistics : nil);
            });
        }
    });
}

#pragma mark - 事件分发核心逻辑

- (DMEventDispatchResult)performEventDispatch:(NSArray<id<DMLifecycleEventListener>> *)listeners 
                                         event:(DMLifecycleEvent)event 
                                         state:(DMLifecycleState)state 
                                      userInfo:(nullable NSDictionary *)userInfo {
    NSUInteger successCount = 0;
    NSUInteger failureCount = 0;
    
    for (id<DMLifecycleEventListener> listener in listeners) {
        BOOL success = [self dispatchToListener:listener event:event state:state userInfo:userInfo];
        if (success) {
            successCount++;
        } else {
            failureCount++;
        }
    }
    
    return [self determineDispatchResult:successCount failureCount:failureCount totalCount:listeners.count];
}

- (BOOL)dispatchToListener:(id<DMLifecycleEventListener>)listener 
                     event:(DMLifecycleEvent)event 
                     state:(DMLifecycleState)state 
                  userInfo:(nullable NSDictionary *)userInfo {
    @try {
        // 检查监听器是否响应对应的方法
        switch (event) {
            case DMLifecycleEventDidFinishLaunching:
                if ([listener respondsToSelector:@selector(onApplicationDidFinishLaunching:)]) {
                    [listener onApplicationDidFinishLaunching:userInfo];
                    return YES;
                }
                break;
                
            case DMLifecycleEventDidBecomeActive:
                if ([listener respondsToSelector:@selector(onApplicationDidBecomeActive)]) {
                    [listener onApplicationDidBecomeActive];
                    return YES;
                }
                break;
                
            case DMLifecycleEventWillResignActive:
                if ([listener respondsToSelector:@selector(onApplicationWillResignActive)]) {
                    [listener onApplicationWillResignActive];
                    return YES;
                }
                break;
                
            case DMLifecycleEventDidEnterBackground:
                if ([listener respondsToSelector:@selector(onApplicationDidEnterBackground)]) {
                    [listener onApplicationDidEnterBackground];
                    return YES;
                }
                break;
                
            case DMLifecycleEventWillEnterForeground:
                if ([listener respondsToSelector:@selector(onApplicationWillEnterForeground)]) {
                    [listener onApplicationWillEnterForeground];
                    return YES;
                }
                break;
                
            case DMLifecycleEventWillTerminate:
                if ([listener respondsToSelector:@selector(onApplicationWillTerminate)]) {
                    [listener onApplicationWillTerminate];
                    return YES;
                }
                break;
                
            case DMLifecycleEventDidReceiveMemoryWarning:
                if ([listener respondsToSelector:@selector(onApplicationDidReceiveMemoryWarning)]) {
                    [listener onApplicationDidReceiveMemoryWarning];
                    return YES;
                }
                break;
                
            default:
                // 对于未知事件，尝试调用通用方法
                if ([listener respondsToSelector:@selector(onLifecycleEvent:withState:userInfo:)]) {
                    [listener onLifecycleEvent:event withState:state userInfo:userInfo];
                    return YES;
                }
                break;
        }
        
        return NO; // 监听器不支持该事件
        
    } @catch (NSException *exception) {
        [self handleDispatchError:[NSError errorWithDomain:@"DMLifecycleEventDispatcher" 
                                                      code:-1 
                                                  userInfo:@{NSLocalizedDescriptionKey: exception.reason ?: @"Unknown error"}]
                            event:event 
                         listener:listener];
        return NO;
    }
}

- (DMEventDispatchResult)determineDispatchResult:(NSUInteger)successCount 
                                    failureCount:(NSUInteger)failureCount 
                                      totalCount:(NSUInteger)totalCount {
    if (totalCount == 0) {
        return DMEventDispatchResultNoListeners;
    }
    
    if (failureCount == 0) {
        return DMEventDispatchResultSuccess;
    } else if (successCount > 0) {
        return DMEventDispatchResultPartialFailure;
    } else {
        return DMEventDispatchResultFailure;
    }
}

#pragma mark - 监听器管理

- (void)addLifecycleEventListener:(id<DMLifecycleEventListener>)listener {
    if (!listener) {
        [self logDebug:@"Cannot add nil lifecycle event listener"];
        return;
    }
    
    [[DMLifecycleDelegateRegistry sharedRegistry] registerLifecycleDelegate:listener];
    [self logDebug:@"Added lifecycle event listener: %@", NSStringFromClass([listener class])];
}

- (void)removeLifecycleEventListener:(id<DMLifecycleEventListener>)listener {
    if (!listener) {
        [self logDebug:@"Cannot remove nil lifecycle event listener"];
        return;
    }
    
    [[DMLifecycleDelegateRegistry sharedRegistry] unregisterLifecycleDelegate:listener];
    [self logDebug:@"Removed lifecycle event listener: %@", NSStringFromClass([listener class])];
}

- (NSUInteger)getActiveListenerCount {
    return [[DMLifecycleDelegateRegistry sharedRegistry] getLifecycleDelegateCount];
}

- (NSUInteger)getListenerCountWithPriority:(NSInteger)priority {
    NSArray *listeners = [[DMLifecycleDelegateRegistry sharedRegistry] getLifecycleDelegatesWithPriority:priority];
    return listeners.count;
}

- (BOOL)hasListenersForEvent:(DMLifecycleEvent)event {
    NSArray<id<DMLifecycleEventListener>> *listeners = [[DMLifecycleDelegateRegistry sharedRegistry] getAllLifecycleDelegates];
    
    for (id<DMLifecycleEventListener> listener in listeners) {
        if ([self listenerSupportsEvent:listener event:event]) {
            return YES;
        }
    }
    
    return NO;
}

- (BOOL)hasStateChangeListeners {
    NSArray<id<DMLifecycleEventListener>> *listeners = [[DMLifecycleDelegateRegistry sharedRegistry] getAllLifecycleDelegates];
    
    for (id<DMLifecycleEventListener> listener in listeners) {
        if ([listener respondsToSelector:@selector(onLifecycleStateChanged:currentState:triggerEvent:)]) {
            return YES;
        }
    }
    
    return NO;
}

- (BOOL)listenerSupportsEvent:(id<DMLifecycleEventListener>)listener event:(DMLifecycleEvent)event {
    switch (event) {
        case DMLifecycleEventDidFinishLaunching:
            return [listener respondsToSelector:@selector(onApplicationDidFinishLaunching:)];
        case DMLifecycleEventDidBecomeActive:
            return [listener respondsToSelector:@selector(onApplicationDidBecomeActive)];
        case DMLifecycleEventWillResignActive:
            return [listener respondsToSelector:@selector(onApplicationWillResignActive)];
        case DMLifecycleEventDidEnterBackground:
            return [listener respondsToSelector:@selector(onApplicationDidEnterBackground)];
        case DMLifecycleEventWillEnterForeground:
            return [listener respondsToSelector:@selector(onApplicationWillEnterForeground)];
        case DMLifecycleEventWillTerminate:
            return [listener respondsToSelector:@selector(onApplicationWillTerminate)];
        case DMLifecycleEventDidReceiveMemoryWarning:
            return [listener respondsToSelector:@selector(onApplicationDidReceiveMemoryWarning)];
        default:
            return [listener respondsToSelector:@selector(onLifecycleEvent:withState:userInfo:)];
    }
}

#pragma mark - 分发控制

- (void)pauseDispatching {
    dispatch_barrier_async(self.dispatchQueue, ^{
        self.dispatchingPaused = YES;
        [self logDebug:@"Event dispatching paused"];
    });
}

- (void)resumeDispatching {
    dispatch_barrier_async(self.dispatchQueue, ^{
        self.dispatchingPaused = NO;
        [self logDebug:@"Event dispatching resumed"];
    });
}

- (BOOL)isDispatchingPaused {
    __block BOOL paused = NO;
    dispatch_sync(self.dispatchQueue, ^{
        paused = self.dispatchingPaused;
    });
    return paused;
}

- (void)cancelPendingDispatches {
    dispatch_barrier_async(self.dispatchQueue, ^{
        [self.pendingDispatches removeAllObjects];
        [self logDebug:@"Cancelled all pending dispatches"];
    });
}

- (BOOL)waitForPendingDispatchesWithTimeout:(NSTimeInterval)timeout {
    dispatch_time_t timeoutTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC));
    long result = dispatch_group_wait(self.dispatchGroup, timeoutTime);
    return result == 0;
}

#pragma mark - 错误处理

- (void)setDispatchErrorHandler:(nullable DMDispatchErrorHandler)errorHandler {
    self.errorHandler = errorHandler;
}

- (void)handleDispatchError:(NSError *)error event:(DMLifecycleEvent)event listener:(id<DMLifecycleEventListener>)listener {
    [self logDebug:@"Dispatch error for event %@: %@", DMLifecycleEventDescription(event), error.localizedDescription];
    
    if (self.errorHandler) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.errorHandler(error, event, listener);
        });
    }
}

#pragma mark - 统计和日志

- (void)updateStatistics:(DMEventDispatchResult)result duration:(NSTimeInterval)duration listenerCount:(NSUInteger)listenerCount {
    if (!self.statisticsEnabled) {
        return;
    }
    
    dispatch_async(self.statisticsQueue, ^{
        self.statistics.totalListeners += listenerCount;
        self.statistics.totalDispatchTime += duration;
        
        if (result == DMEventDispatchResultSuccess || result == DMEventDispatchResultPartialFailure) {
            self.statistics.successfulDispatches++;
        } else {
            self.statistics.failedDispatches++;
        }
    });
}

- (DMDispatchLogItem *)createLogItemForEvent:(DMLifecycleEvent)event state:(DMLifecycleState)state timestamp:(NSDate *)timestamp {
    DMDispatchLogItem *item = [[DMDispatchLogItem alloc] init];
    item.event = event;
    item.state = state;
    item.timestamp = timestamp;
    return item;
}

- (void)addLogItem:(DMDispatchLogItem *)logItem {
    if (!self.debugModeEnabled) {
        return;
    }
    
    dispatch_async(self.statisticsQueue, ^{
        [self.dispatchLog addObject:logItem];
        
        // 限制日志数量
        while (self.dispatchLog.count > self.maxLogCount) {
            [self.dispatchLog removeObjectAtIndex:0];
        }
    });
}

- (nullable DMEventDispatchStatistics *)getDispatchStatistics {
    if (!self.statisticsEnabled) {
        return nil;
    }
    
    __block DMEventDispatchStatistics *stats = nil;
    dispatch_sync(self.statisticsQueue, ^{
        stats = [self.statistics copy];
    });
    return stats;
}

- (void)resetDispatchStatistics {
    dispatch_async(self.statisticsQueue, ^{
        self.statistics = [[DMEventDispatchStatistics alloc] init];
    });
}

- (NSDictionary *)getPerformanceReport {
    __block NSDictionary *report = nil;
    dispatch_sync(self.statisticsQueue, ^{
        report = @{
            @"totalDispatches": @(self.statistics.successfulDispatches + self.statistics.failedDispatches),
            @"successfulDispatches": @(self.statistics.successfulDispatches),
            @"failedDispatches": @(self.statistics.failedDispatches),
            @"averageDispatchTime": @(self.statistics.averageDispatchTime),
            @"totalDispatchTime": @(self.statistics.totalDispatchTime),
            @"activeListeners": @([self getActiveListenerCount]),
            @"dispatchingPaused": @(self.dispatchingPaused),
            @"asyncDispatchEnabled": @(self.asyncDispatchEnabled)
        };
    });
    return report;
}

#pragma mark - 调试支持

- (void)setDebugModeEnabled:(BOOL)enabled {
    self.debugModeEnabled = enabled;
    [self logDebug:@"Debug mode %@", enabled ? @"enabled" : @"disabled"];
}

- (NSDictionary *)getDebugInfo {
    return @{
        @"dispatchingPaused": @(self.dispatchingPaused),
        @"asyncDispatchEnabled": @(self.asyncDispatchEnabled),
        @"statisticsEnabled": @(self.statisticsEnabled),
        @"debugModeEnabled": @(self.debugModeEnabled),
        @"dispatchTimeout": @(self.dispatchTimeout),
        @"maxRetryCount": @(self.maxRetryCount),
        @"activeListeners": @([self getActiveListenerCount]),
        @"logCount": @(self.dispatchLog.count),
        @"maxLogCount": @(self.maxLogCount)
    };
}

- (BOOL)validateDispatcherState {
    // 验证配置参数
    if (self.dispatchTimeout <= 0) {
        [self logDebug:@"Invalid dispatch timeout: %f", self.dispatchTimeout];
        return NO;
    }
    
    if (self.maxRetryCount > 10) {
        [self logDebug:@"Excessive max retry count: %lu", (unsigned long)self.maxRetryCount];
        return NO;
    }
    
    // 验证队列状态
    if (!self.dispatchQueue || !self.statisticsQueue || !self.dispatchGroup) {
        [self logDebug:@"Missing required dispatch queues or group"];
        return NO;
    }
    
    return YES;
}

- (nullable NSString *)exportDispatchLogWithLimit:(NSUInteger)limit {
    __block NSString *jsonString = nil;
    
    dispatch_sync(self.statisticsQueue, ^{
        NSArray *logsToExport = self.dispatchLog;
        if (limit > 0 && limit < logsToExport.count) {
            NSRange range = NSMakeRange(logsToExport.count - limit, limit);
            logsToExport = [logsToExport subarrayWithRange:range];
        }
        
        NSMutableArray *logArray = [NSMutableArray array];
        for (DMDispatchLogItem *item in logsToExport) {
            NSDictionary *logDict = @{
                @"event": DMLifecycleEventDescription(item.event),
                @"eventValue": @(item.event),
                @"state": DMLifecycleStateDescription(item.state),
                @"stateValue": @(item.state),
                @"timestamp": @([item.timestamp timeIntervalSince1970]),
                @"result": @(item.result),
                @"duration": @(item.duration),
                @"listenerCount": @(item.listenerCount),
                @"error": item.errorDescription ?: [NSNull null]
            };
            [logArray addObject:logDict];
        }
        
        NSDictionary *exportData = @{
            @"exportTime": @([[NSDate date] timeIntervalSince1970]),
            @"logCount": @(logArray.count),
            @"logs": logArray
        };
        
        NSError *error = nil;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:exportData
                                                           options:NSJSONWritingPrettyPrinted
                                                             error:&error];
        
        if (jsonData && !error) {
            jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        } else {
            [self logDebug:@"Failed to export dispatch log as JSON: %@", error.localizedDescription];
        }
    });
    
    return jsonString;
}

- (void)logDebug:(NSString *)format, ... {
    if (!self.debugModeEnabled) {
        return;
    }
    
    va_list args;
    va_start(args, format);
    NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);
    
    NSLog(@"[DMLifecycleEventDispatcher] %@", message);
}

@end
